package com.atguigu.tingshu.order.interceptor.impl;

import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.order.interceptor.OrderHandlerInterceptor;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Arrays;

@Slf4j
@Service
public class OrderRepeatSbumitValidOrderHandlerInterceptor implements OrderHandlerInterceptor {
    //表单重复提交的校验

    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Override
    public OrderInfoVo sbumitOrderRequestProcess(OrderInfoVo orderInfoVo) {
        log.info("OrderRepeatSbumitValidOrderHandlerInterceptor....sbumitOrderRequestProcess...执行了");
        /*
        * 用户在提交订单给后端完成之前,又点击了提交订单,这时会导致我们重复提交
        * 解决 将订单标志的travo 在进入页面点击提交之前,保存到redis 点击提交的时候,对redis中的数据进行判断
        * */

        //首先判断传递过来的数据 有没有travo
        String tradeNo = orderInfoVo.getTradeNo();
        if(StringUtils.isEmpty(tradeNo)){
            throw  new GuiguException(ResultCodeEnum.DATA_ERROR);
        }

        //使用lua脚本确保 提交的数据和删除的是同一个
        String script = "if redis.call('exists' , KEYS[1])\n" +
                "then\n" +
                "    return redis.call('del' , KEYS[1])\n" +
                "else\n" +
                "    return 0\n" +
                "end\n" ;
        //为什么redis为空 就是重复提交 因为我们提交完一个数据的是够,会删除该数据 所以当redis数据为空时,就说明之前有数据已经存储过,并且删除了
        Long result = redisTemplate.execute(new DefaultRedisScript<>(script ,Long.class), Arrays.asList(RedisConstant.ORDER_TRADE_NO + tradeNo));
        if(result==0){
            throw new GuiguException(ResultCodeEnum.ORDER_SUBMIT_REPEAT);
        }

        return orderInfoVo;
    }

    @Override
    public int sort() {
        return 2;
    }
}
